package com.kuang.springcloud.config;

import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;

import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 自定义负载均衡算法
 */
//@Configuration
public class djxSuanfa extends AbstractLoadBalancerRule {

    private AtomicInteger nextServerCyclicCounter;
    private static final boolean AVAILABLE_ONLY_SERVERS = true;
    private static final boolean ALL_SERVERS = false;
    private static Logger log = LoggerFactory.getLogger(djxSuanfa.class);

    public djxSuanfa() {
        nextServerCyclicCounter = new AtomicInteger(0);
    }


    public djxSuanfa(ILoadBalancer lb) {
        this();
        setLoadBalancer(lb);
    }

    public Server choose(ILoadBalancer lb, Object key) {
        //如果lb==空 那就没有负载均衡
        if (lb == null) {
            log.warn("no load balancer");
            return null;
        } else {
            Server server = null; //定义客户端为空
            int count = 0; //初始化为0个客户端

            while (server == null && count++ < 10) {//如果 客户端为空 并且客户端小于10
                //获取启动并可以正常访问的服务器列表个数
                int upCount = lb.getReachableServers().size();
                //获取所有的服务器的个数 包括可用和不可用
                List<Server> allServers = lb.getAllServers();
                int serverCount = allServers.size();
                //如果启动正常的服务器为0 和 所有的服务器个数为0
                if ((upCount == 0) || serverCount == 0) {
                    log.warn("没有可用的服务器:" + lb);
                }
                //有正常启动的服务器 获取个数  这时候服务器都是正常的了 可用直接获取全部
                int nextServerIndex = incrementAndGetModulo(serverCount);
                //每次循环获取最下一个服务器
                server = allServers.get(nextServerIndex);
                //如果服务为空
                if (server == null) {
                    //线程礼让 使当前线程由执行状态,变成为就绪状态
                    Thread.yield();
                    continue;//中止本次循环
                }

                //判断线程是否存在   %%  线程是就绪状态
                if (server.isAlive() && (server.isReadyToServe())) {
                    return (server);
                }
                server = null;
            }

            if (count >= 10) {
                log.warn("尝试10次没有可用的服务器: "
                        + lb);
            }
            return server;
        }
    }

    //绑定计数器的模块modulo
    private int incrementAndGetModulo(int modulo) {
        for (; ; ) {//无限循环
            //获取原子性的当前值.get
            int current = nextServerCyclicCounter.get();
            int next = (current + 1) % modulo;
            if (nextServerCyclicCounter.compareAndSet(current, next)) {
                return next;
            }
        }
    }

    @Override
    public Server choose(Object key) {
        return this.choose(this.getLoadBalancer(), key);
    }

    @Override
    public void initWithNiwsConfig(IClientConfig iClientConfig) {

    }


}
